package com.yanx.system.web.query;

import com.querydsl.core.BooleanBuilder;
import com.yanx.common.command.Executor;
import com.yanx.common.core.command.QryCommand;
import com.yanx.common.core.vo.BaseTreeVo;
import com.yanx.common.security.SecurityUtils;
import com.yanx.system.base.domain.entity.QSysMenu;
import com.yanx.system.base.domain.entity.SysUser;
import com.yanx.system.base.domain.entity.rel.QSysRoleMenu;
import com.yanx.system.base.domain.entity.rel.QSysUserRole;
import com.yanx.system.base.model.vo.SysMenuVo;
import com.yanx.system.base.query.SysMenuByIdQry;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单权限分页查询
 *
 * @author: gotanks
 * @create: 2023-2-9
 */
public class SysMenuTreeByUserIdQry extends QryCommand<List<SysMenuVo>> {

    @Override
    public List<SysMenuVo> execute(Executor executor) {
        QSysMenu sysMenu = QSysMenu.sysMenu;
        QSysRoleMenu sysRoleMenu = QSysRoleMenu.sysRoleMenu;
        QSysUserRole sysUserRole = QSysUserRole.sysUserRole;

        //查询条件
        BooleanBuilder condition = new BooleanBuilder();
        condition.and(sysMenu.deleted.eq(false));
        condition.and(sysMenu.status.eq("0"));
        condition.and(sysMenu.menuType.in("M", "C"));
        Long userId = SecurityUtils.getLoginUser().getUserId();
        List<SysMenuVo> menuVoList;
        if (SysUser.isAdmin(userId)) {
            menuVoList = queryFactory.select(SysMenuByIdQry.fields())
                    .from(sysMenu)
                    .where(condition)
                    .orderBy(sysMenu.parentId.asc(), sysMenu.orderNum.asc())
                    .fetch();
        } else {
            menuVoList = queryFactory.select(SysMenuByIdQry.fields())
                    .from(sysMenu)
                    .leftJoin(sysRoleMenu).on(sysRoleMenu.menuId.eq(sysMenu.id))
                    .leftJoin(sysUserRole).on(sysUserRole.roleId.eq(sysRoleMenu.roleId))
                    .where(condition, sysUserRole.userId.eq(userId))
                    .orderBy(sysMenu.parentId.asc(), sysMenu.orderNum.asc())
                    .fetch();
        }

        return (List<SysMenuVo>) getChildPerms(menuVoList);
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list 分类表
     * @return String
     */
    public static List<? extends BaseTreeVo<Long>> getChildPerms(List<? extends BaseTreeVo<Long>> list) {
        List<Long> tempList = list.stream().map(BaseTreeVo::getId).collect(Collectors.toList());
        List<BaseTreeVo<Long>> returnList = new ArrayList<>();
        for (Iterator<? extends BaseTreeVo<Long>> iterator = list.iterator(); iterator.hasNext(); ) {
            BaseTreeVo<Long> t = iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (!tempList.contains(t.getParentId())) {
//            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list 分类表
     * @param t    子节点
     */
    private static void recursionFn(List<? extends BaseTreeVo<Long>> list, BaseTreeVo<Long> t) {
        // 得到子节点列表
        List<? extends BaseTreeVo<Long>> childList = getChildList(list, t);
        t.setChildren(childList);
        for (BaseTreeVo<Long> tChild : childList) {
            if (getChildList(list, tChild).size() > 0) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private static List<? extends BaseTreeVo<Long>> getChildList(List<? extends BaseTreeVo<Long>> list, BaseTreeVo<Long> t) {
        return list.stream().filter(n -> Objects.equals(n.getParentId(), t.getId())).collect(Collectors.toList());
    }

}